package cn.wolfcode.wolf2w.controller;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.Travel;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.search.domain.DestinationEs;
import cn.wolfcode.wolf2w.search.domain.StrategyEs;
import cn.wolfcode.wolf2w.search.domain.TravelEs;
import cn.wolfcode.wolf2w.search.domain.UserInfoEs;
import cn.wolfcode.wolf2w.search.query.SearchQueryObject;
import cn.wolfcode.wolf2w.search.service.ISearchService;
import cn.wolfcode.wolf2w.search.vo.SearchResultVo;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.service.ITravelService;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.JsonResult;
import cn.wolfcode.wolf2w.util.ParamMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class SearchController {

    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private ITravelService travelService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ISearchService searchService;


    @GetMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {
        String kw = URLDecoder.decode(qo.getKeyword(), "UTF-8");
        qo.setKeyword(kw);
        switch (qo.getType()) {
            case SearchQueryObject.TYPE_DEST:
                return SearchDest(qo);
            case SearchQueryObject.TYPE_STRATEGY:
                return SearchStrategy(qo);
            case SearchQueryObject.TYPE_TRAVEL:
                return SearchTravel(qo);
            case SearchQueryObject.TYPE_USER:
                return SearchUser(qo);
            default:
                return SearchAll(qo);
        }

    }
    //搜索全部
    private Object SearchAll(SearchQueryObject qo) {
        SearchResultVo vo = new SearchResultVo();
        long total = 0L;

        Page<UserInfo> us = this.createUserInfoPage(qo);
        vo.setUsers(us.getContent());
        total += us.getTotalElements();

        Page<Travel> ts = this.createTravelPage(qo);
        vo.setTravels(ts.getContent());
        total += ts.getTotalElements();

        Page<Strategy> sts = this.createStrategyPage(qo);
        vo.setStrategys(sts.getContent());
        total += sts.getTotalElements();

        Page<Destination> ds = this.createDestinationPage(qo);
        vo.setDests(ds.getContent());
        total += ds.getTotalElements();
        vo.setTotal(total);

       /* Map<String ,Object> map=new HashMap<>();
        map.put("result",vo);
        map.put("qo",qo);
*/
        return JsonResult.success(new ParamMap().put("result", vo).put("qo", qo));
    }
    //搜索用户
    private Object SearchUser(SearchQueryObject qo) {
    /*    Map<String, Object> map = new HashMap<>();
        map.put("page", page);
        map.put("qo", qo);*/
        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createUserInfoPage(qo)));
    }
    //搜索游记
    private Object SearchTravel(SearchQueryObject qo) {
        //Page<Travel> page = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME, Travel.class, qo, "title", "summary");

       /* Map<String, Object> map = new HashMap<>();
        map.put("page", page);
        map.put("qo", qo)*/

        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createTravelPage(qo)));
    }

    //攻略
    private Object SearchStrategy(SearchQueryObject qo) {

        //Page<Strategy> page = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME, Strategy.class, qo, "title", "subtitle", "summary");
/*
        Map<String, Object> map = new HashMap<>();
        map.put("page", page);
        map.put("qo", qo);*/
        return JsonResult.success(new ParamMap().put("qo", qo).put("page", this.createStrategyPage(qo)));
    }

    //目的地
    private Object SearchDest(SearchQueryObject qo) {

        Destination dest = destinationService.findByName(qo.getKeyword());

        SearchResultVo vo = new SearchResultVo();
        if (dest != null) {

            List<Strategy> sts = strategyService.queryByDestName(qo.getKeyword());
            vo.setStrategys(sts);

            List<Travel> ts = travelService.queryByDestName(qo.getKeyword());
            vo.setTravels(ts);
            List<UserInfo> us = userInfoService.queryByCity(qo.getKeyword());
            vo.setUsers(us);

            long total = sts.size() + ts.size() + us.size();
            vo.setTotal(total);
        }

/*        Map<String, Object> map = new HashMap<>();
        map.put("result", vo);
        map.put("qo", qo);
        map.put("dest", dest);*/

        return JsonResult.success(new ParamMap().put("result", vo).put("qo", qo).put("dest", dest));
    }

    private Page<UserInfo> createUserInfoPage(SearchQueryObject qo) {
        Page<UserInfo> us = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class, qo, "city", "info");
        return us;
    }

    private Page<Travel> createTravelPage(SearchQueryObject qo) {
        Page<Travel> ts = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME,
                Travel.class, qo, "title", "summary");
        return ts;
    }

    private Page<Strategy> createStrategyPage(SearchQueryObject qo) {
        Page<Strategy> sts = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class, qo, "title", "subtitle", "summary");
        return sts;
    }

    private Page<Destination> createDestinationPage(SearchQueryObject qo) {
        Page<Destination> ds = searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME,
                Destination.class, qo, "name", "info");
        return ds;
    }
}
